<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="Mybatis练习">
<meta property="og:type" content="article">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/Mybatis/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="Mybatis练习">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729111159534.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729112907106.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729113304743.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729164450524.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/.io//image-20210729165337223.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729165724838.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729171208737.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729171146911.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729172544230.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729173210433.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729180118287.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729180604529.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729180709318.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729182223137.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729184156019.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729184756094.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729185128686.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729185030318.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729203804276.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729204458815.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729212510291.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729213613029.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729214548756.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729214917317.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729215351651.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729215537167.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729220348255.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729221207962.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729221049462.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729221058898.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729222642700.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729224205522.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729224549305.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729225713894.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210805230303461.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210805231727206.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210805235229938.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210805235405070.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210805234302849.png">
<meta property="og:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210805234842497.png">
<meta property="article:published_time" content="2021-11-17T14:30:53.984Z">
<meta property="article:modified_time" content="2021-11-17T14:59:58.364Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://renshengdian.gitee.io/renshengdian/2021/11/17/images/assets/image-20210729111159534.png">
  
    <link rel="alternate" href="/renshengdian/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/renshengdian/favicon.png">
  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">

  
  
<link rel="stylesheet" href="/renshengdian/css/style.css">

  
    
<link rel="stylesheet" href="/renshengdian/fancybox/jquery.fancybox.min.css">

  
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/renshengdian/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/renshengdian/">Home</a>
        
          <a class="main-nav-link" href="/renshengdian/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/renshengdian/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://renshengdian.gitee.io/renshengdian"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-Mybatis" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/renshengdian/2021/11/17/Mybatis/" class="article-date">
  <time class="dt-published" datetime="2021-11-17T14:30:53.984Z" itemprop="datePublished">2021-11-17</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="Mybatis练习"><a href="#Mybatis练习" class="headerlink" title="Mybatis练习"></a>Mybatis练习</h2><span id="more"></span>

<p><strong>目标</strong></p>
<blockquote>
<ul>
<li>能够使用映射配置文件实现CRUD操作</li>
<li>能够使用注解实现CRUD操作</li>
</ul>
</blockquote>
<h2 id="1，配置文件实现CRUD"><a href="#1，配置文件实现CRUD" class="headerlink" title="1，配置文件实现CRUD"></a>1，配置文件实现CRUD</h2><p><img src="../images/assets/image-20210729111159534.png" alt="image-20210729111159534"></p>
<p>如上图所示产品原型，里面包含了品牌数据的 <code>查询</code> 、<code>按条件查询</code>、<code>添加</code>、<code>删除</code>、<code>批量删除</code>、<code>修改</code> 等功能，而这些功能其实就是对数据库表中的数据进行CRUD操作。接下来我们就使用Mybatis完成品牌数据的增删改查操作。以下是我们要完成功能列表：</p>
<blockquote>
<ul>
<li>查询<ul>
<li>查询所有数据</li>
<li>查询详情</li>
<li>条件查询</li>
</ul>
</li>
<li>添加</li>
<li>修改<ul>
<li>修改全部字段</li>
<li>修改动态字段</li>
</ul>
</li>
<li>删除<ul>
<li>删除一个</li>
<li>批量删除</li>
</ul>
</li>
</ul>
</blockquote>
<p>我们先将必要的环境准备一下。</p>
<h3 id="1-1-环境准备"><a href="#1-1-环境准备" class="headerlink" title="1.1  环境准备"></a>1.1  环境准备</h3><ul>
<li><p>数据库表（tb_brand）及数据准备</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 删除tb_brand表</span></span><br><span class="line"><span class="keyword">drop</span> <span class="keyword">table</span> if <span class="keyword">exists</span> tb_brand;</span><br><span class="line"><span class="comment">-- 创建tb_brand表</span></span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> tb_brand</span><br><span class="line">(</span><br><span class="line">    <span class="comment">-- id 主键</span></span><br><span class="line">    id           <span class="type">int</span> <span class="keyword">primary</span> key auto_increment,</span><br><span class="line">    <span class="comment">-- 品牌名称</span></span><br><span class="line">    brand_name   <span class="type">varchar</span>(<span class="number">20</span>),</span><br><span class="line">    <span class="comment">-- 企业名称</span></span><br><span class="line">    company_name <span class="type">varchar</span>(<span class="number">20</span>),</span><br><span class="line">    <span class="comment">-- 排序字段</span></span><br><span class="line">    ordered      <span class="type">int</span>,</span><br><span class="line">    <span class="comment">-- 描述信息</span></span><br><span class="line">    description  <span class="type">varchar</span>(<span class="number">100</span>),</span><br><span class="line">    <span class="comment">-- 状态：0：禁用  1：启用</span></span><br><span class="line">    status       <span class="type">int</span></span><br><span class="line">);</span><br><span class="line"><span class="comment">-- 添加数据</span></span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> tb_brand (brand_name, company_name, ordered, description, status)</span><br><span class="line"><span class="keyword">values</span> (<span class="string">&#x27;三只松鼠&#x27;</span>, <span class="string">&#x27;三只松鼠股份有限公司&#x27;</span>, <span class="number">5</span>, <span class="string">&#x27;好吃不上火&#x27;</span>, <span class="number">0</span>),</span><br><span class="line">       (<span class="string">&#x27;华为&#x27;</span>, <span class="string">&#x27;华为技术有限公司&#x27;</span>, <span class="number">100</span>, <span class="string">&#x27;华为致力于把数字世界带入每个人、每个家庭、每个组织，构建万物互联的智能世界&#x27;</span>, <span class="number">1</span>),</span><br><span class="line">       (<span class="string">&#x27;小米&#x27;</span>, <span class="string">&#x27;小米科技有限公司&#x27;</span>, <span class="number">50</span>, <span class="string">&#x27;are you ok&#x27;</span>, <span class="number">1</span>);</span><br></pre></td></tr></table></figure></li>
<li><p>实体类 Brand</p>
<p>在 <code>com.itheima.pojo</code> 包下创建 Brand 实体类。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Brand</span> </span>&#123;</span><br><span class="line">    <span class="comment">// id 主键</span></span><br><span class="line">    <span class="keyword">private</span> Integer id;</span><br><span class="line">    <span class="comment">// 品牌名称</span></span><br><span class="line">    <span class="keyword">private</span> String brandName;</span><br><span class="line">    <span class="comment">// 企业名称</span></span><br><span class="line">    <span class="keyword">private</span> String companyName;</span><br><span class="line">    <span class="comment">// 排序字段</span></span><br><span class="line">    <span class="keyword">private</span> Integer ordered;</span><br><span class="line">    <span class="comment">// 描述信息</span></span><br><span class="line">    <span class="keyword">private</span> String description;</span><br><span class="line">    <span class="comment">// 状态：0：禁用  1：启用</span></span><br><span class="line">    <span class="keyword">private</span> Integer status;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//省略 setter and getter。自己写时要补全这部分代码</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
<li><p>编写测试用例</p>
<p>测试代码需要在 <code>test/java</code> 目录下创建包及测试用例。项目结构如下：</p>
<img src="../images/assets/image-20210729112907106.png" alt="image-20210729112907106" style="zoom:80%;"></li>
<li><p>安装 MyBatisX 插件</p>
<ul>
<li><p>MybatisX 是一款基于 IDEA 的快速开发插件，为效率而生。</p>
</li>
<li><p>主要功能</p>
<ul>
<li>XML映射配置文件 和 接口方法 间相互跳转</li>
<li>根据接口方法生成 statement </li>
</ul>
</li>
<li><p>安装方式</p>
<p>点击 <code>file</code> ，选择 <code>settings</code> ，就能看到如下图所示界面</p>
<img src="../images/assets/image-20210729113304743.png" alt="image-20210729113304743" style="zoom:80%;">

<blockquote>
<p>注意：安装完毕后需要重启IDEA</p>
</blockquote>
</li>
<li><p>插件效果</p>
<img src="../images/assets/image-20210729164450524.png" alt="image-20210729164450524" style="zoom:70%;">

<p>红色头绳的表示映射配置文件，蓝色头绳的表示mapper接口。在mapper接口点击红色头绳的小鸟图标会自动跳转到对应的映射配置文件，在映射配置文件中点击蓝色头绳的小鸟图标会自动跳转到对应的mapper接口。也可以在mapper接口中定义方法，自动生成映射配置文件中的 <code>statement</code> ，如图所示</p>
<p><img src="/renshengdian/.io//image-20210729165337223.png" alt="image-20210729165337223"></p>
</li>
</ul>
</li>
</ul>
<h3 id="1-2-查询所有数据"><a href="#1-2-查询所有数据" class="headerlink" title="1.2  查询所有数据"></a>1.2  查询所有数据</h3><img src="../images/assets/image-20210729165724838.png" alt="image-20210729165724838" style="zoom:80%;">

<p>如上图所示就页面上展示的数据，而这些数据需要从数据库进行查询。接下来我们就来讲查询所有数据功能，而实现该功能我们分以下步骤进行实现：</p>
<ul>
<li><p>编写接口方法：Mapper接口</p>
<ul>
<li><p>参数：无</p>
<p>查询所有数据功能是不需要根据任何条件进行查询的，所以此方法不需要参数。</p>
<img src="../images/assets/image-20210729171208737.png" alt="image-20210729171208737" style="zoom:80%;"></li>
<li><p>结果：List<Brand></Brand></p>
<p>我们会将查询出来的每一条数据封装成一个 <code>Brand</code> 对象，而多条数据封装多个 <code>Brand</code> 对象，需要将这些对象封装到List集合中返回。</p>
<img src="../images/assets/image-20210729171146911.png" alt="image-20210729171146911" style="zoom:80%;"></li>
<li><p>执行方法、测试</p>
</li>
</ul>
</li>
</ul>
<h4 id="1-2-1-编写接口方法"><a href="#1-2-1-编写接口方法" class="headerlink" title="1.2.1  编写接口方法"></a>1.2.1  编写接口方法</h4><p>在 <code>com.itheima.mapper</code> 包写创建名为 <code>BrandMapper</code> 的接口。并在该接口中定义 <code>List&lt;Brand&gt; selectAll()</code> 方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">BrandMapper</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 查询所有</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function">List&lt;Brand&gt; <span class="title">selectAll</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="1-2-2-编写SQL语句"><a href="#1-2-2-编写SQL语句" class="headerlink" title="1.2.2  编写SQL语句"></a>1.2.2  编写SQL语句</h4><p>在 <code>reources</code> 下创建 <code>com/itheima/mapper</code> 目录结构，并在该目录下创建名为 <code>BrandMapper.xml</code> 的映射配置文件</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;</span></span><br><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">mapper</span></span></span><br><span class="line"><span class="meta">        <span class="meta-keyword">PUBLIC</span> <span class="meta-string">&quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;</span></span></span><br><span class="line"><span class="meta">        <span class="meta-string">&quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">mapper</span> <span class="attr">namespace</span>=<span class="string">&quot;com.itheima.mapper.BrandMapper&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectAll&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;brand&quot;</span>&gt;</span></span><br><span class="line">        select *</span><br><span class="line">        from tb_brand;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">mapper</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="1-2-3-编写测试方法"><a href="#1-2-3-编写测试方法" class="headerlink" title="1.2.3  编写测试方法"></a>1.2.3  编写测试方法</h4><p>在 <code>MybatisTest</code> 类中编写测试查询所有的方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testSelectAll</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">    <span class="comment">//1. 获取SqlSessionFactory</span></span><br><span class="line">    String resource = <span class="string">&quot;mybatis-config.xml&quot;</span>;</span><br><span class="line">    InputStream inputStream = Resources.getResourceAsStream(resource);</span><br><span class="line">    SqlSessionFactory sqlSessionFactory = <span class="keyword">new</span> SqlSessionFactoryBuilder().build(inputStream);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//2. 获取SqlSession对象</span></span><br><span class="line">    SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line"></span><br><span class="line">    <span class="comment">//3. 获取Mapper接口的代理对象</span></span><br><span class="line">    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//4. 执行方法</span></span><br><span class="line">    List&lt;Brand&gt; brands = brandMapper.selectAll();</span><br><span class="line">    System.out.println(brands);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//5. 释放资源</span></span><br><span class="line">    sqlSession.close();</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>注意：现在我们感觉测试这部分代码写起来特别麻烦，我们可以先忍忍。以后我们只会写上面的第3步的代码，其他的都不需要我们来完成。</p>
</blockquote>
<p>执行测试方法结果如下：</p>
<p><img src="../images/assets/image-20210729172544230.png" alt="image-20210729172544230"></p>
<p>从上面结果我们看到了问题，有些数据封装成功了，而有些数据并没有封装成功。为什么这样呢？</p>
<p>这个问题可以通过两种方式进行解决：</p>
<ul>
<li>给字段起别名</li>
<li>使用resultMap定义字段和属性的映射关系</li>
</ul>
<h4 id="1-2-4-起别名解决上述问题"><a href="#1-2-4-起别名解决上述问题" class="headerlink" title="1.2.4  起别名解决上述问题"></a>1.2.4  起别名解决上述问题</h4><p>从上面结果可以看到 <code>brandName</code> 和 <code>companyName</code> 这两个属性的数据没有封装成功，查询 实体类 和 表中的字段 发现，在实体类中属性名是 <code>brandName</code> 和 <code>companyName</code> ，而表中的字段名为 <code>brand_name</code> 和 <code>company_name</code>，如下图所示 。那么我们只需要保持这两部分的名称一致这个问题就迎刃而解。</p>
<img src="../images/assets/image-20210729173210433.png" alt="image-20210729173210433" style="zoom:80%;">

<p>我们可以在写sql语句时给这两个字段起别名，将别名定义成和属性名一致即可。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectAll&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;brand&quot;</span>&gt;</span></span><br><span class="line">    select</span><br><span class="line">    id, brand_name as brandName, company_name as companyName, ordered, description, status</span><br><span class="line">    from tb_brand;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>而上面的SQL语句中的字段列表书写麻烦，如果表中还有更多的字段，同时其他的功能也需要查询这些字段时就显得我们的代码不够精炼。Mybatis提供了<code>sql</code> 片段可以提高sql的复用性。</p>
<p><strong>SQL片段：</strong></p>
<ul>
<li><p>将需要复用的SQL片段抽取到 <code>sql</code> 标签中</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">sql</span> <span class="attr">id</span>=<span class="string">&quot;brand_column&quot;</span>&gt;</span></span><br><span class="line">	id, brand_name as brandName, company_name as companyName, ordered, description, status</span><br><span class="line"><span class="tag">&lt;/<span class="name">sql</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>id属性值是唯一标识，引用时也是通过该值进行引用。</p>
</li>
<li><p>在原sql语句中进行引用</p>
<p>使用 <code>include</code> 标签引用上述的 SQL 片段，而 <code>refid</code> 指定上述 SQL 片段的id值。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectAll&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;brand&quot;</span>&gt;</span></span><br><span class="line">    select</span><br><span class="line">    <span class="tag">&lt;<span class="name">include</span> <span class="attr">refid</span>=<span class="string">&quot;brand_column&quot;</span> /&gt;</span></span><br><span class="line">    from tb_brand;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
<h4 id="1-2-5-使用resultMap解决上述问题"><a href="#1-2-5-使用resultMap解决上述问题" class="headerlink" title="1.2.5  使用resultMap解决上述问题"></a>1.2.5  使用resultMap解决上述问题</h4><p>起别名 + sql片段的方式可以解决上述问题，但是它也存在问题。如果还有功能只需要查询部分字段，而不是查询所有字段，那么我们就需要再定义一个 SQL 片段，这就显得不是那么灵活。</p>
<p>那么我们也可以使用resultMap来定义字段和属性的映射关系的方式解决上述问题。</p>
<ul>
<li><p>在映射配置文件中使用resultMap定义 字段 和 属性 的映射关系</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">resultMap</span> <span class="attr">id</span>=<span class="string">&quot;brandResultMap&quot;</span> <span class="attr">type</span>=<span class="string">&quot;brand&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            id：完成主键字段的映射</span></span><br><span class="line"><span class="comment">                column：表的列名</span></span><br><span class="line"><span class="comment">                property：实体类的属性名</span></span><br><span class="line"><span class="comment">            result：完成一般字段的映射</span></span><br><span class="line"><span class="comment">                column：表的列名</span></span><br><span class="line"><span class="comment">                property：实体类的属性名</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">result</span> <span class="attr">column</span>=<span class="string">&quot;brand_name&quot;</span> <span class="attr">property</span>=<span class="string">&quot;brandName&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">result</span> <span class="attr">column</span>=<span class="string">&quot;company_name&quot;</span> <span class="attr">property</span>=<span class="string">&quot;companyName&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">resultMap</span>&gt;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>注意：在上面只需要定义 字段名 和 属性名 不一样的映射，而一样的则不需要专门定义出来。</p>
</blockquote>
</li>
<li><p>SQL语句正常编写</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectAll&quot;</span> <span class="attr">resultMap</span>=<span class="string">&quot;brandResultMap&quot;</span>&gt;</span></span><br><span class="line">    select *</span><br><span class="line">    from tb_brand;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
<h4 id="1-2-6-小结"><a href="#1-2-6-小结" class="headerlink" title="1.2.6  小结"></a>1.2.6  小结</h4><p>实体类属性名 和 数据库表列名 不一致，不能自动封装数据</p>
<ul>
<li>==起别名：==在SQL语句中，对不一样的列名起别名，别名和实体类属性名一样<ul>
<li>可以定义 <sql>片段，提升复用性 </sql></li>
</ul>
</li>
<li>==resultMap：==定义<resultMap> 完成不一致的属性名和列名的映射</resultMap></li>
</ul>
<p>而我们最终选择使用 resultMap的方式。查询映射配置文件中查询所有的 statement 书写如下：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"> <span class="tag">&lt;<span class="name">resultMap</span> <span class="attr">id</span>=<span class="string">&quot;brandResultMap&quot;</span> <span class="attr">type</span>=<span class="string">&quot;brand&quot;</span>&gt;</span></span><br><span class="line">     <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            id：完成主键字段的映射</span></span><br><span class="line"><span class="comment">                column：表的列名</span></span><br><span class="line"><span class="comment">                property：实体类的属性名</span></span><br><span class="line"><span class="comment">            result：完成一般字段的映射</span></span><br><span class="line"><span class="comment">                column：表的列名</span></span><br><span class="line"><span class="comment">                property：实体类的属性名</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">result</span> <span class="attr">column</span>=<span class="string">&quot;brand_name&quot;</span> <span class="attr">property</span>=<span class="string">&quot;brandName&quot;</span>/&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">result</span> <span class="attr">column</span>=<span class="string">&quot;company_name&quot;</span> <span class="attr">property</span>=<span class="string">&quot;companyName&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">resultMap</span>&gt;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectAll&quot;</span> <span class="attr">resultMap</span>=<span class="string">&quot;brandResultMap&quot;</span>&gt;</span></span><br><span class="line">    select *</span><br><span class="line">    from tb_brand;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>



<h3 id="1-3-查询详情"><a href="#1-3-查询详情" class="headerlink" title="1.3  查询详情"></a>1.3  查询详情</h3><img src="../images/assets/image-20210729180118287.png" alt="image-20210729180118287" style="zoom:80%;">

<p>有些数据的属性比较多，在页面表格中无法全部实现，而只会显示部分，而其他属性数据的查询可以通过 <code>查看详情</code> 来进行查询，如上图所示。</p>
<p>查看详情功能实现步骤：</p>
<ul>
<li><p>编写接口方法：Mapper接口</p>
<img src="../images/assets/image-20210729180604529.png" alt="image-20210729180604529" style="zoom:80%;">

<ul>
<li><p>参数：id</p>
<p>查看详情就是查询某一行数据，所以需要根据id进行查询。而id以后是由页面传递过来。</p>
</li>
<li><p>结果：Brand</p>
<p>根据id查询出来的数据只要一条，而将一条数据封装成一个Brand对象即可</p>
</li>
</ul>
</li>
<li><p>编写SQL语句：SQL映射文件</p>
<img src="../images/assets/image-20210729180709318.png" alt="image-20210729180709318" style="zoom:80%;"></li>
<li><p>执行方法、进行测试</p>
</li>
</ul>
<h4 id="1-3-1-编写接口方法"><a href="#1-3-1-编写接口方法" class="headerlink" title="1.3.1  编写接口方法"></a>1.3.1  编写接口方法</h4><p>在 <code>BrandMapper</code> 接口中定义根据id查询数据的方法 </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  * 查看详情：根据Id查询</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"><span class="function">Brand <span class="title">selectById</span><span class="params">(<span class="keyword">int</span> id)</span></span>;</span><br></pre></td></tr></table></figure>

<h4 id="1-3-2-编写SQL语句"><a href="#1-3-2-编写SQL语句" class="headerlink" title="1.3.2  编写SQL语句"></a>1.3.2  编写SQL语句</h4><p>在 <code>BrandMapper.xml</code> 映射配置文件中编写 <code>statement</code>，使用 <code>resultMap</code> 而不是使用 <code>resultType</code></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectById&quot;</span>  <span class="attr">resultMap</span>=<span class="string">&quot;brandResultMap&quot;</span>&gt;</span></span><br><span class="line">    select *</span><br><span class="line">    from tb_brand where id = #&#123;id&#125;;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>注意：上述SQL中的 #{id}先这样写，一会我们再详细讲解</p>
</blockquote>
<h4 id="1-3-3-编写测试方法"><a href="#1-3-3-编写测试方法" class="headerlink" title="1.3.3  编写测试方法"></a>1.3.3  编写测试方法</h4><p>在 <code>test/java</code> 下的 <code>com.itheima.mapper</code>  包下的 <code>MybatisTest类中</code> 定义测试方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"> <span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testSelectById</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">    <span class="comment">//接收参数，该id以后需要传递过来</span></span><br><span class="line">    <span class="keyword">int</span> id = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//1. 获取SqlSessionFactory</span></span><br><span class="line">    String resource = <span class="string">&quot;mybatis-config.xml&quot;</span>;</span><br><span class="line">    InputStream inputStream = Resources.getResourceAsStream(resource);</span><br><span class="line">    SqlSessionFactory sqlSessionFactory = <span class="keyword">new</span> SqlSessionFactoryBuilder().build(inputStream);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//2. 获取SqlSession对象</span></span><br><span class="line">    SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line"></span><br><span class="line">    <span class="comment">//3. 获取Mapper接口的代理对象</span></span><br><span class="line">    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//4. 执行方法</span></span><br><span class="line">    Brand brand = brandMapper.selectById(id);</span><br><span class="line">    System.out.println(brand);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//5. 释放资源</span></span><br><span class="line">    sqlSession.close();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>执行测试方法结果如下：</p>
<img src="../images/assets/image-20210729182223137.png" alt="image-20210729182223137" style="zoom:70%;">

<h4 id="1-3-4-参数占位符"><a href="#1-3-4-参数占位符" class="headerlink" title="1.3.4  参数占位符"></a>1.3.4  参数占位符</h4><p>查询到的结果很好理解就是id为1的这行数据。而这里我们需要看控制台显示的SQL语句，能看到使用？进行占位。说明我们在映射配置文件中的写的 <code>#&#123;id&#125;</code> 最终会被？进行占位。接下来我们就聊聊映射配置文件中的参数占位符。</p>
<p>mybatis提供了两种参数占位符：</p>
<ul>
<li><p>#{} ：执行SQL时，会将 #{} 占位符替换为？，将来自动设置参数值。从上述例子可以看出使用#{} 底层使用的是 <code>PreparedStatement</code></p>
</li>
<li><p>${} ：拼接SQL。底层使用的是 <code>Statement</code>，会存在SQL注入问题。如下图将 映射配置文件中的 #{} 替换成 ${} 来看效果</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectById&quot;</span>  <span class="attr">resultMap</span>=<span class="string">&quot;brandResultMap&quot;</span>&gt;</span></span><br><span class="line">    select *</span><br><span class="line">    from tb_brand where id = $&#123;id&#125;;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>重新运行查看结果如下：</p>
<img src="../images/assets/image-20210729184156019.png" alt="image-20210729184156019" style="zoom:70%;"></li>
</ul>
<blockquote>
<p>==注意：==从上面两个例子可以看出，以后开发我们使用 #{} 参数占位符。</p>
</blockquote>
<h4 id="1-3-5-parameterType使用"><a href="#1-3-5-parameterType使用" class="headerlink" title="1.3.5  parameterType使用"></a>1.3.5  parameterType使用</h4><p>对于有参数的mapper接口方法，我们在映射配置文件中应该配置 <code>ParameterType</code> 来指定参数类型。只不过该属性都可以省略。如下图：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectById&quot;</span> <span class="attr">parameterType</span>=<span class="string">&quot;int&quot;</span> <span class="attr">resultMap</span>=<span class="string">&quot;brandResultMap&quot;</span>&gt;</span></span><br><span class="line">    select *</span><br><span class="line">    from tb_brand where id = $&#123;id&#125;;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="1-3-6-SQL语句中特殊字段处理"><a href="#1-3-6-SQL语句中特殊字段处理" class="headerlink" title="1.3.6  SQL语句中特殊字段处理"></a>1.3.6  SQL语句中特殊字段处理</h4><p>以后肯定会在SQL语句中写一下特殊字符，比如某一个字段大于某个值，如下图</p>
<img src="../images/assets/image-20210729184756094.png" alt="image-20210729184756094" style="zoom:80%;">

<p>可以看出报错了，因为映射配置文件是xml类型的问题，而 &gt; &lt; 等这些字符在xml中有特殊含义，所以此时我们需要将这些符号进行转义，可以使用以下两种方式进行转义</p>
<ul>
<li><p>转义字符</p>
<p>下图的 <code>&amp;lt;</code> 就是 <code>&lt;</code> 的转义字符。</p>
<img src="../images/assets/image-20210729185128686.png" alt="image-20210729185128686" style="zoom:60%;"></li>
<li><!--[CDATA[内容]]-->

<img src="../images/assets/image-20210729185030318.png" alt="image-20210729185030318" style="zoom:60%;"></li>
</ul>
<h3 id="1-4-多条件查询"><a href="#1-4-多条件查询" class="headerlink" title="1.4  多条件查询"></a>1.4  多条件查询</h3><p><img src="../images/assets/image-20210729203804276.png" alt="image-20210729203804276"></p>
<p>我们经常会遇到如上图所示的多条件查询，将多条件查询的结果展示在下方的数据列表中。而我们做这个功能需要分析最终的SQL语句应该是什么样，思考两个问题</p>
<ul>
<li>条件表达式</li>
<li>如何连接</li>
</ul>
<p>条件字段 <code>企业名称</code>  和 <code>品牌名称</code> 需要进行模糊查询，所以条件应该是：</p>
<img src="../images/assets/image-20210729204458815.png" alt="image-20210729204458815" style="zoom:70%;">

<p>简单的分析后，我们来看功能实现的步骤：</p>
<ul>
<li><p>编写接口方法</p>
<ul>
<li>参数：所有查询条件</li>
<li>结果：List<Brand></Brand></li>
</ul>
</li>
<li><p>在映射配置文件中编写SQL语句</p>
</li>
<li><p>编写测试方法并执行</p>
</li>
</ul>
<h4 id="1-4-1-编写接口方法"><a href="#1-4-1-编写接口方法" class="headerlink" title="1.4.1  编写接口方法"></a>1.4.1  编写接口方法</h4><p>在 <code>BrandMapper</code> 接口中定义多条件查询的方法。</p>
<p>而该功能有三个参数，我们就需要考虑定义接口时，参数应该如何定义。Mybatis针对多参数有多种实现</p>
<ul>
<li><p>使用 <code>@Param(&quot;参数名称&quot;)</code> 标记每一个参数，在映射配置文件中就需要使用 <code>#&#123;参数名称&#125;</code> 进行占位</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">List&lt;Brand&gt; <span class="title">selectByCondition</span><span class="params">(<span class="meta">@Param(&quot;status&quot;)</span> <span class="keyword">int</span> status, <span class="meta">@Param(&quot;companyName&quot;)</span> String companyName,<span class="meta">@Param(&quot;brandName&quot;)</span> String brandName)</span></span>;</span><br></pre></td></tr></table></figure></li>
<li><p>将多个参数封装成一个 实体对象 ，将该实体对象作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 <code>#&#123;内容&#125;</code> 时，里面的内容必须和实体类属性名保持一致。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">List&lt;Brand&gt; <span class="title">selectByCondition</span><span class="params">(Brand brand)</span></span>;</span><br></pre></td></tr></table></figure></li>
<li><p>将多个参数封装到map集合中，将map集合作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 <code>#&#123;内容&#125;</code> 时，里面的内容必须和map集合中键的名称一致。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;Brand&gt; selectByCondition(Map map);</span><br></pre></td></tr></table></figure></li>
</ul>
<h4 id="1-4-2-编写SQL语句"><a href="#1-4-2-编写SQL语句" class="headerlink" title="1.4.2  编写SQL语句"></a>1.4.2  编写SQL语句</h4><p>在 <code>BrandMapper.xml</code> 映射配置文件中编写 <code>statement</code>，使用 <code>resultMap</code> 而不是使用 <code>resultType</code></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectByCondition&quot;</span> <span class="attr">resultMap</span>=<span class="string">&quot;brandResultMap&quot;</span>&gt;</span></span><br><span class="line">    select *</span><br><span class="line">    from tb_brand</span><br><span class="line">    where status = #&#123;status&#125;</span><br><span class="line">    and company_name like #&#123;companyName&#125;</span><br><span class="line">    and brand_name like #&#123;brandName&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="1-4-3-编写测试方法"><a href="#1-4-3-编写测试方法" class="headerlink" title="1.4.3  编写测试方法"></a>1.4.3  编写测试方法</h4><p>在 <code>test/java</code> 下的 <code>com.itheima.mapper</code>  包下的 <code>MybatisTest类中</code> 定义测试方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testSelectByCondition</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">    <span class="comment">//接收参数</span></span><br><span class="line">    <span class="keyword">int</span> status = <span class="number">1</span>;</span><br><span class="line">    String companyName = <span class="string">&quot;华为&quot;</span>;</span><br><span class="line">    String brandName = <span class="string">&quot;华为&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 处理参数</span></span><br><span class="line">    companyName = <span class="string">&quot;%&quot;</span> + companyName + <span class="string">&quot;%&quot;</span>;</span><br><span class="line">    brandName = <span class="string">&quot;%&quot;</span> + brandName + <span class="string">&quot;%&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//1. 获取SqlSessionFactory</span></span><br><span class="line">    String resource = <span class="string">&quot;mybatis-config.xml&quot;</span>;</span><br><span class="line">    InputStream inputStream = Resources.getResourceAsStream(resource);</span><br><span class="line">    SqlSessionFactory sqlSessionFactory = <span class="keyword">new</span> SqlSessionFactoryBuilder().build(inputStream);</span><br><span class="line">    <span class="comment">//2. 获取SqlSession对象</span></span><br><span class="line">    SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">    <span class="comment">//3. 获取Mapper接口的代理对象</span></span><br><span class="line">    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//4. 执行方法</span></span><br><span class="line">	<span class="comment">//方式一 ：接口方法参数使用 @Param 方式调用的方法</span></span><br><span class="line">    <span class="comment">//List&lt;Brand&gt; brands = brandMapper.selectByCondition(status, companyName, brandName);</span></span><br><span class="line">    <span class="comment">//方式二 ：接口方法参数是 实体类对象 方式调用的方法</span></span><br><span class="line">     <span class="comment">//封装对象</span></span><br><span class="line">    <span class="comment">/* Brand brand = new Brand();</span></span><br><span class="line"><span class="comment">        brand.setStatus(status);</span></span><br><span class="line"><span class="comment">        brand.setCompanyName(companyName);</span></span><br><span class="line"><span class="comment">        brand.setBrandName(brandName);*/</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//List&lt;Brand&gt; brands = brandMapper.selectByCondition(brand);</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//方式三 ：接口方法参数是 map集合对象 方式调用的方法</span></span><br><span class="line">    Map map = <span class="keyword">new</span> HashMap();</span><br><span class="line">    map.put(<span class="string">&quot;status&quot;</span> , status);</span><br><span class="line">    map.put(<span class="string">&quot;companyName&quot;</span>, companyName);</span><br><span class="line">    map.put(<span class="string">&quot;brandName&quot;</span> , brandName);</span><br><span class="line">    List&lt;Brand&gt; brands = brandMapper.selectByCondition(map);</span><br><span class="line">    System.out.println(brands);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//5. 释放资源</span></span><br><span class="line">    sqlSession.close();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="1-4-4-动态SQL"><a href="#1-4-4-动态SQL" class="headerlink" title="1.4.4  动态SQL"></a>1.4.4  动态SQL</h4><p>上述功能实现存在很大的问题。用户在输入条件时，肯定不会所有的条件都填写，这个时候我们的SQL语句就不能那样写的</p>
<p>例如用户只输入 当前状态 时，SQL语句就是</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_brand <span class="keyword">where</span> status <span class="operator">=</span> #&#123;status&#125;</span><br></pre></td></tr></table></figure>

<p>而用户如果只输入企业名称时，SQL语句就是</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_brand <span class="keyword">where</span> company_name <span class="keyword">like</span> #&#123;companName&#125;</span><br></pre></td></tr></table></figure>

<p>而用户如果输入了 <code>当前状态</code> 和 <code>企业名称 </code> 时，SQL语句又不一样</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_brand <span class="keyword">where</span> status <span class="operator">=</span> #&#123;status&#125; <span class="keyword">and</span> company_name <span class="keyword">like</span> #&#123;companName&#125;</span><br></pre></td></tr></table></figure>

<p>针对上述的需要，Mybatis对动态SQL有很强大的支撑：</p>
<blockquote>
<ul>
<li><p>if</p>
</li>
<li><p>choose (when, otherwise)</p>
</li>
<li><p>trim (where, set)</p>
</li>
<li><p>foreach</p>
</li>
</ul>
</blockquote>
<p>我们先学习 if 标签和 where 标签：</p>
<ul>
<li><p>if 标签：条件判断</p>
<ul>
<li>test 属性：逻辑表达式</li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectByCondition&quot;</span> <span class="attr">resultMap</span>=<span class="string">&quot;brandResultMap&quot;</span>&gt;</span></span><br><span class="line">    select *</span><br><span class="line">    from tb_brand</span><br><span class="line">    where</span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;status != null&quot;</span>&gt;</span></span><br><span class="line">            and status = #&#123;status&#125;</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;companyName != null and companyName != &#x27;&#x27; &quot;</span>&gt;</span></span><br><span class="line">            and company_name like #&#123;companyName&#125;</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;brandName != null and brandName != &#x27;&#x27; &quot;</span>&gt;</span></span><br><span class="line">            and brand_name like #&#123;brandName&#125;</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>如上的这种SQL语句就会根据传递的参数值进行动态的拼接。如果此时status和companyName有值那么就会值拼接这两个条件。</p>
<p>执行结果如下：</p>
<p><img src="../images/assets/image-20210729212510291.png" alt="image-20210729212510291"></p>
<p>但是它也存在问题，如果此时给的参数值是</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Map map = <span class="keyword">new</span> HashMap();</span><br><span class="line"><span class="comment">// map.put(&quot;status&quot; , status);</span></span><br><span class="line">map.put(<span class="string">&quot;companyName&quot;</span>, companyName);</span><br><span class="line">map.put(<span class="string">&quot;brandName&quot;</span> , brandName);</span><br></pre></td></tr></table></figure>

<p>拼接的SQL语句就变成了</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_brand <span class="keyword">where</span> <span class="keyword">and</span> company_name <span class="keyword">like</span> ? <span class="keyword">and</span> brand_name <span class="keyword">like</span> ?</span><br></pre></td></tr></table></figure>

<p>而上面的语句中 where 关键后直接跟 and 关键字，这就是一条错误的SQL语句。这个就可以使用 where 标签解决</p>
</li>
<li><p>where 标签</p>
<ul>
<li>作用：<ul>
<li>替换where关键字</li>
<li>会动态的去掉第一个条件前的 and </li>
<li>如果所有的参数没有值则不加where关键字</li>
</ul>
</li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectByCondition&quot;</span> <span class="attr">resultMap</span>=<span class="string">&quot;brandResultMap&quot;</span>&gt;</span></span><br><span class="line">    select *</span><br><span class="line">    from tb_brand</span><br><span class="line">    <span class="tag">&lt;<span class="name">where</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;status != null&quot;</span>&gt;</span></span><br><span class="line">            and status = #&#123;status&#125;</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;companyName != null and companyName != &#x27;&#x27; &quot;</span>&gt;</span></span><br><span class="line">            and company_name like #&#123;companyName&#125;</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;brandName != null and brandName != &#x27;&#x27; &quot;</span>&gt;</span></span><br><span class="line">            and brand_name like #&#123;brandName&#125;</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">where</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>注意：需要给每个条件前都加上 and 关键字。</p>
</blockquote>
</li>
</ul>
<h3 id="1-5-单个条件（动态SQL）"><a href="#1-5-单个条件（动态SQL）" class="headerlink" title="1.5 单个条件（动态SQL）"></a>1.5 单个条件（动态SQL）</h3><img src="../images/assets/image-20210729213613029.png" alt="image-20210729213613029" style="zoom:80%;">

<p>如上图所示，在查询时只能选择 <code>品牌名称</code>、<code>当前状态</code>、<code>企业名称</code> 这三个条件中的一个，但是用户到底选择哪儿一个，我们并不能确定。这种就属于单个条件的动态SQL语句。 </p>
<p>这种需求需要使用到  <code>choose（when，otherwise）标签</code>  实现，  而 <code>choose</code> 标签类似于Java 中的switch语句。</p>
<p>通过一个案例来使用这些标签</p>
<h4 id="1-5-1-编写接口方法"><a href="#1-5-1-编写接口方法" class="headerlink" title="1.5.1  编写接口方法"></a>1.5.1  编写接口方法</h4><p>在 <code>BrandMapper</code> 接口中定义单条件查询的方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  * 单条件动态查询</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@param</span> brand</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"><span class="function">List&lt;Brand&gt; <span class="title">selectByConditionSingle</span><span class="params">(Brand brand)</span></span>;</span><br></pre></td></tr></table></figure>

<h4 id="1-5-2-编写SQL语句"><a href="#1-5-2-编写SQL语句" class="headerlink" title="1.5.2  编写SQL语句"></a>1.5.2  编写SQL语句</h4><p>在 <code>BrandMapper.xml</code> 映射配置文件中编写 <code>statement</code>，使用 <code>resultMap</code> 而不是使用 <code>resultType</code></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;selectByConditionSingle&quot;</span> <span class="attr">resultMap</span>=<span class="string">&quot;brandResultMap&quot;</span>&gt;</span></span><br><span class="line">    select *</span><br><span class="line">    from tb_brand</span><br><span class="line">    <span class="tag">&lt;<span class="name">where</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">choose</span>&gt;</span><span class="comment">&lt;!--相当于switch--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">when</span> <span class="attr">test</span>=<span class="string">&quot;status != null&quot;</span>&gt;</span><span class="comment">&lt;!--相当于case--&gt;</span></span><br><span class="line">                status = #&#123;status&#125;</span><br><span class="line">            <span class="tag">&lt;/<span class="name">when</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">when</span> <span class="attr">test</span>=<span class="string">&quot;companyName != null and companyName != &#x27;&#x27; &quot;</span>&gt;</span><span class="comment">&lt;!--相当于case--&gt;</span></span><br><span class="line">                company_name like #&#123;companyName&#125;</span><br><span class="line">            <span class="tag">&lt;/<span class="name">when</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">when</span> <span class="attr">test</span>=<span class="string">&quot;brandName != null and brandName != &#x27;&#x27;&quot;</span>&gt;</span><span class="comment">&lt;!--相当于case--&gt;</span></span><br><span class="line">                brand_name like #&#123;brandName&#125;</span><br><span class="line">            <span class="tag">&lt;/<span class="name">when</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">choose</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">where</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="1-5-3-编写测试方法"><a href="#1-5-3-编写测试方法" class="headerlink" title="1.5.3  编写测试方法"></a>1.5.3  编写测试方法</h4><p>在 <code>test/java</code> 下的 <code>com.itheima.mapper</code>  包下的 <code>MybatisTest类中</code> 定义测试方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testSelectByConditionSingle</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">    <span class="comment">//接收参数</span></span><br><span class="line">    <span class="keyword">int</span> status = <span class="number">1</span>;</span><br><span class="line">    String companyName = <span class="string">&quot;华为&quot;</span>;</span><br><span class="line">    String brandName = <span class="string">&quot;华为&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 处理参数</span></span><br><span class="line">    companyName = <span class="string">&quot;%&quot;</span> + companyName + <span class="string">&quot;%&quot;</span>;</span><br><span class="line">    brandName = <span class="string">&quot;%&quot;</span> + brandName + <span class="string">&quot;%&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//封装对象</span></span><br><span class="line">    Brand brand = <span class="keyword">new</span> Brand();</span><br><span class="line">    <span class="comment">//brand.setStatus(status);</span></span><br><span class="line">    brand.setCompanyName(companyName);</span><br><span class="line">    <span class="comment">//brand.setBrandName(brandName);</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//1. 获取SqlSessionFactory</span></span><br><span class="line">    String resource = <span class="string">&quot;mybatis-config.xml&quot;</span>;</span><br><span class="line">    InputStream inputStream = Resources.getResourceAsStream(resource);</span><br><span class="line">    SqlSessionFactory sqlSessionFactory = <span class="keyword">new</span> SqlSessionFactoryBuilder().build(inputStream);</span><br><span class="line">    <span class="comment">//2. 获取SqlSession对象</span></span><br><span class="line">    SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">    <span class="comment">//3. 获取Mapper接口的代理对象</span></span><br><span class="line">    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);</span><br><span class="line">    <span class="comment">//4. 执行方法</span></span><br><span class="line">    List&lt;Brand&gt; brands = brandMapper.selectByConditionSingle(brand);</span><br><span class="line">    System.out.println(brands);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//5. 释放资源</span></span><br><span class="line">    sqlSession.close();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>执行测试方法结果如下：</p>
<img src="../images/assets/image-20210729214548756.png" alt="image-20210729214548756" style="zoom:70%;">

<h3 id="1-6-添加数据"><a href="#1-6-添加数据" class="headerlink" title="1.6  添加数据"></a>1.6  添加数据</h3><img src="../images/assets/image-20210729214917317.png" alt="image-20210729214917317" style="zoom:70%;">

<p>如上图是我们平时在添加数据时展示的页面，而我们在该页面输入想要的数据后添加 <code>提交</code> 按钮，就会将这些数据添加到数据库中。接下来我们就来实现添加数据的操作。</p>
<ul>
<li><p>编写接口方法</p>
<img src="../images/assets/image-20210729215351651.png" alt="image-20210729215351651" style="zoom:80%;">

<p>参数：除了id之外的所有的数据。id对应的是表中主键值，而主键我们是 ==自动增长== 生成的。</p>
</li>
<li><p>编写SQL语句</p>
<img src="../images/assets/image-20210729215537167.png" alt="image-20210729215537167" style="zoom:80%;"></li>
<li><p>编写测试方法并执行</p>
</li>
</ul>
<p>明确了该功能实现的步骤后，接下来我们进行具体的操作。</p>
<h4 id="1-6-1-编写接口方法"><a href="#1-6-1-编写接口方法" class="headerlink" title="1.6.1  编写接口方法"></a>1.6.1  编写接口方法</h4><p>在 <code>BrandMapper</code> 接口中定义添加方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * 添加</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">add</span><span class="params">(Brand brand)</span></span>;</span><br></pre></td></tr></table></figure>

<h4 id="1-6-2-编写SQL语句"><a href="#1-6-2-编写SQL语句" class="headerlink" title="1.6.2  编写SQL语句"></a>1.6.2  编写SQL语句</h4><p>在 <code>BrandMapper.xml</code> 映射配置文件中编写添加数据的 <code>statement</code></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">insert</span> <span class="attr">id</span>=<span class="string">&quot;add&quot;</span>&gt;</span></span><br><span class="line">    insert into tb_brand (brand_name, company_name, ordered, description, status)</span><br><span class="line">    values (#&#123;brandName&#125;, #&#123;companyName&#125;, #&#123;ordered&#125;, #&#123;description&#125;, #&#123;status&#125;);</span><br><span class="line"><span class="tag">&lt;/<span class="name">insert</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="1-6-3-编写测试方法"><a href="#1-6-3-编写测试方法" class="headerlink" title="1.6.3  编写测试方法"></a>1.6.3  编写测试方法</h4><p>在 <code>test/java</code> 下的 <code>com.itheima.mapper</code>  包下的 <code>MybatisTest类中</code> 定义测试方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testAdd</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">    <span class="comment">//接收参数</span></span><br><span class="line">    <span class="keyword">int</span> status = <span class="number">1</span>;</span><br><span class="line">    String companyName = <span class="string">&quot;波导手机&quot;</span>;</span><br><span class="line">    String brandName = <span class="string">&quot;波导&quot;</span>;</span><br><span class="line">    String description = <span class="string">&quot;手机中的战斗机&quot;</span>;</span><br><span class="line">    <span class="keyword">int</span> ordered = <span class="number">100</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//封装对象</span></span><br><span class="line">    Brand brand = <span class="keyword">new</span> Brand();</span><br><span class="line">    brand.setStatus(status);</span><br><span class="line">    brand.setCompanyName(companyName);</span><br><span class="line">    brand.setBrandName(brandName);</span><br><span class="line">    brand.setDescription(description);</span><br><span class="line">    brand.setOrdered(ordered);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//1. 获取SqlSessionFactory</span></span><br><span class="line">    String resource = <span class="string">&quot;mybatis-config.xml&quot;</span>;</span><br><span class="line">    InputStream inputStream = Resources.getResourceAsStream(resource);</span><br><span class="line">    SqlSessionFactory sqlSessionFactory = <span class="keyword">new</span> SqlSessionFactoryBuilder().build(inputStream);</span><br><span class="line">    <span class="comment">//2. 获取SqlSession对象</span></span><br><span class="line">    SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">    <span class="comment">//SqlSession sqlSession = sqlSessionFactory.openSession(true); //设置自动提交事务，这种情况不需要手动提交事务了</span></span><br><span class="line">    <span class="comment">//3. 获取Mapper接口的代理对象</span></span><br><span class="line">    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);</span><br><span class="line">    <span class="comment">//4. 执行方法</span></span><br><span class="line">    brandMapper.add(brand);</span><br><span class="line">    <span class="comment">//提交事务</span></span><br><span class="line">    sqlSession.commit();</span><br><span class="line">    <span class="comment">//5. 释放资源</span></span><br><span class="line">    sqlSession.close();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>执行结果如下：</p>
<p><img src="../images/assets/image-20210729220348255.png" alt="image-20210729220348255"></p>
<h4 id="1-6-4-添加-主键返回"><a href="#1-6-4-添加-主键返回" class="headerlink" title="1.6.4  添加-主键返回"></a>1.6.4  添加-主键返回</h4><p>在数据添加成功后，有时候需要获取插入数据库数据的主键（主键是自增长）。</p>
<p>比如：添加订单和订单项，如下图就是京东上的订单</p>
<img src="../images/assets/image-20210729221207962.png" alt="image-20210729221207962" style="zoom:80%;">

<p>订单数据存储在订单表中，订单项存储在订单项表中。</p>
<ul>
<li><p>添加订单数据</p>
<img src="../images/assets/image-20210729221049462.png" alt="image-20210729221049462" style="zoom:80%;"></li>
<li><p>添加订单项数据，订单项中需要设置所属订单的id</p>
<img src="../images/assets/image-20210729221058898.png" alt="image-20210729221058898" style="zoom:80%;"></li>
</ul>
<p>明白了什么时候 <code>主键返回</code> 。接下来我们简单模拟一下，在添加完数据后打印id属性值，能打印出来说明已经获取到了。</p>
<p>我们将上面添加品牌数据的案例中映射配置文件里 <code>statement</code> 进行修改，如下</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">insert</span> <span class="attr">id</span>=<span class="string">&quot;add&quot;</span> <span class="attr">useGeneratedKeys</span>=<span class="string">&quot;true&quot;</span> <span class="attr">keyProperty</span>=<span class="string">&quot;id&quot;</span>&gt;</span></span><br><span class="line">    insert into tb_brand (brand_name, company_name, ordered, description, status)</span><br><span class="line">    values (#&#123;brandName&#125;, #&#123;companyName&#125;, #&#123;ordered&#125;, #&#123;description&#125;, #&#123;status&#125;);</span><br><span class="line"><span class="tag">&lt;/<span class="name">insert</span>&gt;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>在 insert 标签上添加如下属性：</p>
<ul>
<li>useGeneratedKeys：是够获取自动增长的主键值。true表示获取</li>
<li>keyProperty  ：指定将获取到的主键值封装到哪儿个属性里</li>
</ul>
</blockquote>
<h3 id="1-7-修改"><a href="#1-7-修改" class="headerlink" title="1.7  修改"></a>1.7  修改</h3><img src="../images/assets/image-20210729222642700.png" alt="image-20210729222642700" style="zoom:80%;">

<p>如图所示是修改页面，用户在该页面书写需要修改的数据，点击 <code>提交</code> 按钮，就会将数据库中对应的数据进行修改。注意一点，如果哪儿个输入框没有输入内容，我们是将表中数据对应字段值替换为空白还是保留字段之前的值？答案肯定是保留之前的数据。</p>
<p>接下来我们就具体来实现</p>
<h4 id="1-7-1-编写接口方法"><a href="#1-7-1-编写接口方法" class="headerlink" title="1.7.1  编写接口方法"></a>1.7.1  编写接口方法</h4><p>在 <code>BrandMapper</code> 接口中定义修改方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * 修改</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">update</span><span class="params">(Brand brand)</span></span>;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>上述方法参数 Brand 就是封装了需要修改的数据，而id肯定是有数据的，这也是和添加方法的区别。</p>
</blockquote>
<h4 id="1-7-2-编写SQL语句"><a href="#1-7-2-编写SQL语句" class="headerlink" title="1.7.2  编写SQL语句"></a>1.7.2  编写SQL语句</h4><p>在 <code>BrandMapper.xml</code> 映射配置文件中编写修改数据的 <code>statement</code>。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">update</span> <span class="attr">id</span>=<span class="string">&quot;update&quot;</span>&gt;</span></span><br><span class="line">    update tb_brand</span><br><span class="line">    <span class="tag">&lt;<span class="name">set</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;brandName != null and brandName != &#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">            brand_name = #&#123;brandName&#125;,</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;companyName != null and companyName != &#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">            company_name = #&#123;companyName&#125;,</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;ordered != null&quot;</span>&gt;</span></span><br><span class="line">            ordered = #&#123;ordered&#125;,</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;description != null and description != &#x27;&#x27;&quot;</span>&gt;</span></span><br><span class="line">            description = #&#123;description&#125;,</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">&quot;status != null&quot;</span>&gt;</span></span><br><span class="line">            status = #&#123;status&#125;</span><br><span class="line">        <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br><span class="line">    where id = #&#123;id&#125;;</span><br><span class="line"><span class="tag">&lt;/<span class="name">update</span>&gt;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p><em>set</em> 标签可以用于动态包含需要更新的列，忽略其它不更新的列。</p>
</blockquote>
<h4 id="1-7-3-编写测试方法"><a href="#1-7-3-编写测试方法" class="headerlink" title="1.7.3  编写测试方法"></a>1.7.3  编写测试方法</h4><p>在 <code>test/java</code> 下的 <code>com.itheima.mapper</code>  包下的 <code>MybatisTest类中</code> 定义测试方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testUpdate</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">    <span class="comment">//接收参数</span></span><br><span class="line">    <span class="keyword">int</span> status = <span class="number">0</span>;</span><br><span class="line">    String companyName = <span class="string">&quot;波导手机&quot;</span>;</span><br><span class="line">    String brandName = <span class="string">&quot;波导&quot;</span>;</span><br><span class="line">    String description = <span class="string">&quot;波导手机,手机中的战斗机&quot;</span>;</span><br><span class="line">    <span class="keyword">int</span> ordered = <span class="number">200</span>;</span><br><span class="line">    <span class="keyword">int</span> id = <span class="number">6</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//封装对象</span></span><br><span class="line">    Brand brand = <span class="keyword">new</span> Brand();</span><br><span class="line">    brand.setStatus(status);</span><br><span class="line">    <span class="comment">//        brand.setCompanyName(companyName);</span></span><br><span class="line">    <span class="comment">//        brand.setBrandName(brandName);</span></span><br><span class="line">    <span class="comment">//        brand.setDescription(description);</span></span><br><span class="line">    <span class="comment">//        brand.setOrdered(ordered);</span></span><br><span class="line">    brand.setId(id);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//1. 获取SqlSessionFactory</span></span><br><span class="line">    String resource = <span class="string">&quot;mybatis-config.xml&quot;</span>;</span><br><span class="line">    InputStream inputStream = Resources.getResourceAsStream(resource);</span><br><span class="line">    SqlSessionFactory sqlSessionFactory = <span class="keyword">new</span> SqlSessionFactoryBuilder().build(inputStream);</span><br><span class="line">    <span class="comment">//2. 获取SqlSession对象</span></span><br><span class="line">    SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">    <span class="comment">//SqlSession sqlSession = sqlSessionFactory.openSession(true);</span></span><br><span class="line">    <span class="comment">//3. 获取Mapper接口的代理对象</span></span><br><span class="line">    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);</span><br><span class="line">    <span class="comment">//4. 执行方法</span></span><br><span class="line">    <span class="keyword">int</span> count = brandMapper.update(brand);</span><br><span class="line">    System.out.println(count);</span><br><span class="line">    <span class="comment">//提交事务</span></span><br><span class="line">    sqlSession.commit();</span><br><span class="line">    <span class="comment">//5. 释放资源</span></span><br><span class="line">    sqlSession.close();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>执行测试方法结果如下：</p>
<p><img src="../images/assets/image-20210729224205522.png" alt="image-20210729224205522"></p>
<p>从结果中SQL语句可以看出，只修改了 <code>status</code>  字段值，因为我们给的数据中只给Brand实体对象的 <code>status</code> 属性设置值了。这就是 <code>set</code> 标签的作用。</p>
<h3 id="1-8-删除一行数据"><a href="#1-8-删除一行数据" class="headerlink" title="1.8  删除一行数据"></a>1.8  删除一行数据</h3><p><img src="../images/assets/image-20210729224549305.png" alt="image-20210729224549305"></p>
<p>如上图所示，每行数据后面都有一个 <code>删除</code> 按钮，当用户点击了该按钮，就会将改行数据删除掉。那我们就需要思考，这种删除是根据什么进行删除呢？是通过主键id删除，因为id是表中数据的唯一标识。</p>
<p>接下来就来实现该功能。</p>
<h4 id="1-8-1-编写接口方法"><a href="#1-8-1-编写接口方法" class="headerlink" title="1.8.1  编写接口方法"></a>1.8.1  编写接口方法</h4><p>在 <code>BrandMapper</code> 接口中定义根据id删除方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  * 根据id删除</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">deleteById</span><span class="params">(<span class="keyword">int</span> id)</span></span>;</span><br></pre></td></tr></table></figure>

<h4 id="1-8-2-编写SQL语句"><a href="#1-8-2-编写SQL语句" class="headerlink" title="1.8.2  编写SQL语句"></a>1.8.2  编写SQL语句</h4><p>在 <code>BrandMapper.xml</code> 映射配置文件中编写删除一行数据的 <code>statement</code></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">delete</span> <span class="attr">id</span>=<span class="string">&quot;deleteById&quot;</span>&gt;</span></span><br><span class="line">    delete from tb_brand where id = #&#123;id&#125;;</span><br><span class="line"><span class="tag">&lt;/<span class="name">delete</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="1-8-3-编写测试方法"><a href="#1-8-3-编写测试方法" class="headerlink" title="1.8.3  编写测试方法"></a>1.8.3  编写测试方法</h4><p>在 <code>test/java</code> 下的 <code>com.itheima.mapper</code>  包下的 <code>MybatisTest类中</code> 定义测试方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"> <span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testDeleteById</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">    <span class="comment">//接收参数</span></span><br><span class="line">    <span class="keyword">int</span> id = <span class="number">6</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//1. 获取SqlSessionFactory</span></span><br><span class="line">    String resource = <span class="string">&quot;mybatis-config.xml&quot;</span>;</span><br><span class="line">    InputStream inputStream = Resources.getResourceAsStream(resource);</span><br><span class="line">    SqlSessionFactory sqlSessionFactory = <span class="keyword">new</span> SqlSessionFactoryBuilder().build(inputStream);</span><br><span class="line">    <span class="comment">//2. 获取SqlSession对象</span></span><br><span class="line">    SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">    <span class="comment">//SqlSession sqlSession = sqlSessionFactory.openSession(true);</span></span><br><span class="line">    <span class="comment">//3. 获取Mapper接口的代理对象</span></span><br><span class="line">    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);</span><br><span class="line">    <span class="comment">//4. 执行方法</span></span><br><span class="line">    brandMapper.deleteById(id);</span><br><span class="line">    <span class="comment">//提交事务</span></span><br><span class="line">    sqlSession.commit();</span><br><span class="line">    <span class="comment">//5. 释放资源</span></span><br><span class="line">    sqlSession.close();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>运行过程只要没报错，直接到数据库查询数据是否还存在。</p>
<h3 id="1-9-批量删除"><a href="#1-9-批量删除" class="headerlink" title="1.9  批量删除"></a>1.9  批量删除</h3><img src="../images/assets/image-20210729225713894.png" alt="image-20210729225713894" style="zoom:70%;">



<p>如上图所示，用户可以选择多条数据，然后点击上面的 <code>删除</code> 按钮，就会删除数据库中对应的多行数据。</p>
<h4 id="1-9-1-编写接口方法"><a href="#1-9-1-编写接口方法" class="headerlink" title="1.9.1  编写接口方法"></a>1.9.1  编写接口方法</h4><p>在 <code>BrandMapper</code> 接口中定义删除多行数据的方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  * 批量删除</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">deleteByIds</span><span class="params">(<span class="keyword">int</span>[] ids)</span></span>;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>参数是一个数组，数组中存储的是多条数据的id</p>
</blockquote>
<h4 id="1-9-2-编写SQL语句"><a href="#1-9-2-编写SQL语句" class="headerlink" title="1.9.2  编写SQL语句"></a>1.9.2  编写SQL语句</h4><p>在 <code>BrandMapper.xml</code> 映射配置文件中编写删除多条数据的 <code>statement</code>。</p>
<p>编写SQL时需要遍历数组来拼接SQL语句。Mybatis 提供了 <code>foreach</code> 标签供我们使用</p>
<p><strong>foreach 标签</strong></p>
<p>用来迭代任何可迭代的对象（如数组，集合）。</p>
<ul>
<li>collection 属性：<ul>
<li>mybatis会将数组参数，封装为一个Map集合。<ul>
<li>默认：array = 数组</li>
<li>使用@Param注解改变map集合的默认key的名称</li>
</ul>
</li>
</ul>
</li>
<li>item 属性：本次迭代获取到的元素。</li>
<li>separator 属性：集合项迭代之间的分隔符。<code>foreach</code> 标签不会错误地添加多余的分隔符。也就是最后一次迭代不会加分隔符。</li>
<li>open 属性：该属性值是在拼接SQL语句之前拼接的语句，只会拼接一次</li>
<li>close 属性：该属性值是在拼接SQL语句拼接后拼接的语句，只会拼接一次</li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">delete</span> <span class="attr">id</span>=<span class="string">&quot;deleteByIds&quot;</span>&gt;</span></span><br><span class="line">    delete from tb_brand where id</span><br><span class="line">    in</span><br><span class="line">    <span class="tag">&lt;<span class="name">foreach</span> <span class="attr">collection</span>=<span class="string">&quot;array&quot;</span> <span class="attr">item</span>=<span class="string">&quot;id&quot;</span> <span class="attr">separator</span>=<span class="string">&quot;,&quot;</span> <span class="attr">open</span>=<span class="string">&quot;(&quot;</span> <span class="attr">close</span>=<span class="string">&quot;)&quot;</span>&gt;</span></span><br><span class="line">        #&#123;id&#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">foreach</span>&gt;</span></span><br><span class="line">    ;</span><br><span class="line"><span class="tag">&lt;/<span class="name">delete</span>&gt;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>假如数组中的id数据是{1,2,3}，那么拼接后的sql语句就是：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">delete</span> <span class="keyword">from</span> tb_brand <span class="keyword">where</span> id <span class="keyword">in</span> (<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>);</span><br></pre></td></tr></table></figure>
</blockquote>
<h4 id="1-9-3-编写测试方法"><a href="#1-9-3-编写测试方法" class="headerlink" title="1.9.3  编写测试方法"></a>1.9.3  编写测试方法</h4><p>在 <code>test/java</code> 下的 <code>com.itheima.mapper</code>  包下的 <code>MybatisTest类中</code> 定义测试方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testDeleteByIds</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">    <span class="comment">//接收参数</span></span><br><span class="line">    <span class="keyword">int</span>[] ids = &#123;<span class="number">5</span>,<span class="number">7</span>,<span class="number">8</span>&#125;;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//1. 获取SqlSessionFactory</span></span><br><span class="line">    String resource = <span class="string">&quot;mybatis-config.xml&quot;</span>;</span><br><span class="line">    InputStream inputStream = Resources.getResourceAsStream(resource);</span><br><span class="line">    SqlSessionFactory sqlSessionFactory = <span class="keyword">new</span> SqlSessionFactoryBuilder().build(inputStream);</span><br><span class="line">    <span class="comment">//2. 获取SqlSession对象</span></span><br><span class="line">    SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">    <span class="comment">//SqlSession sqlSession = sqlSessionFactory.openSession(true);</span></span><br><span class="line">    <span class="comment">//3. 获取Mapper接口的代理对象</span></span><br><span class="line">    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);</span><br><span class="line">    <span class="comment">//4. 执行方法</span></span><br><span class="line">    brandMapper.deleteByIds(ids);</span><br><span class="line">    <span class="comment">//提交事务</span></span><br><span class="line">    sqlSession.commit();</span><br><span class="line">    <span class="comment">//5. 释放资源</span></span><br><span class="line">    sqlSession.close();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="1-10-Mybatis参数传递"><a href="#1-10-Mybatis参数传递" class="headerlink" title="1.10  Mybatis参数传递"></a>1.10  Mybatis参数传递</h3><p>Mybatis 接口方法中可以接收各种各样的参数，如下：</p>
<ul>
<li>多个参数</li>
<li>单个参数：单个参数又可以是如下类型<ul>
<li>POJO 类型</li>
<li>Map 集合类型</li>
<li>Collection 集合类型</li>
<li>List 集合类型</li>
<li>Array 类型</li>
<li>其他类型</li>
</ul>
</li>
</ul>
<h4 id="1-10-1-多个参数"><a href="#1-10-1-多个参数" class="headerlink" title="1.10.1  多个参数"></a>1.10.1  多个参数</h4><p>如下面的代码，就是接收两个参数，而接收多个参数需要使用 <code>@Param</code> 注解，那么为什么要加该注解呢？这个问题要弄明白就必须来研究Mybatis 底层对于这些参数是如何处理的。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">User <span class="title">select</span><span class="params">(<span class="meta">@Param(&quot;username&quot;)</span> String username,<span class="meta">@Param(&quot;password&quot;)</span> String password)</span></span>;</span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;select&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">	select *</span><br><span class="line">    from tb_user</span><br><span class="line">    where </span><br><span class="line">    	username=#&#123;username&#125;</span><br><span class="line">    	and password=#&#123;password&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>我们在接口方法中定义多个参数，Mybatis 会将这些参数封装成 Map 集合对象，值就是参数值，而键在没有使用 <code>@Param</code> 注解时有以下命名规则：</p>
<ul>
<li><p>以 arg 开头  ：第一个参数就叫 arg0，第二个参数就叫 arg1，以此类推。如：</p>
<blockquote>
<p>map.put(“arg0”，参数值1);</p>
<p>map.put(“arg1”，参数值2);</p>
</blockquote>
</li>
<li><p>以 param 开头 ： 第一个参数就叫 param1，第二个参数就叫 param2，依次类推。如：</p>
<blockquote>
<p>map.put(“param1”，参数值1);</p>
<p>map.put(“param2”，参数值2);</p>
</blockquote>
</li>
</ul>
<p><strong>代码验证：</strong></p>
<ul>
<li><p>在 <code>UserMapper</code> 接口中定义如下方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">User <span class="title">select</span><span class="params">(String username,String password)</span></span>;</span><br></pre></td></tr></table></figure></li>
<li><p>在 <code>UserMapper.xml</code> 映射配置文件中定义SQL</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;select&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">	select *</span><br><span class="line">    from tb_user</span><br><span class="line">    where </span><br><span class="line">    	username=#&#123;arg0&#125;</span><br><span class="line">    	and password=#&#123;arg1&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>或者</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;select&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">	select *</span><br><span class="line">    from tb_user</span><br><span class="line">    where </span><br><span class="line">    	username=#&#123;param1&#125;</span><br><span class="line">    	and password=#&#123;param2&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
<li><p>运行代码结果如下</p>
<img src="../images/assets/image-20210805230303461.png" alt="image-20210805230303461" style="zoom:80%;">

<p>在映射配合文件的SQL语句中使用用 <code>arg</code> 开头的和 <code>param</code> 书写，代码的可读性会变的特别差，此时可以使用 <code>@Param</code> 注解。</p>
</li>
</ul>
<p>在接口方法参数上使用 <code>@Param</code> 注解，Mybatis 会将 <code>arg</code> 开头的键名替换为对应注解的属性值。</p>
<p><strong>代码验证：</strong></p>
<ul>
<li><p>在 <code>UserMapper</code> 接口中定义如下方法，在 <code>username</code> 参数前加上 <code>@Param</code> 注解</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">User <span class="title">select</span><span class="params">(<span class="meta">@Param(&quot;username&quot;)</span> String username, String password)</span></span>;</span><br></pre></td></tr></table></figure>

<p>Mybatis 在封装 Map 集合时，键名就会变成如下：</p>
<blockquote>
<p>map.put(“username”，参数值1);</p>
<p>map.put(“arg1”，参数值2);</p>
<p>map.put(“param1”，参数值1);</p>
<p>map.put(“param2”，参数值2);</p>
</blockquote>
</li>
<li><p>在 <code>UserMapper.xml</code> 映射配置文件中定义SQL</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;select&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">	select *</span><br><span class="line">    from tb_user</span><br><span class="line">    where </span><br><span class="line">    	username=#&#123;username&#125;</span><br><span class="line">    	and password=#&#123;param2&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
<li><p>运行程序结果没有报错。而如果将 <code>#&#123;&#125;</code> 中的 <code>username</code> 还是写成  <code>arg0</code> </p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">&quot;select&quot;</span> <span class="attr">resultType</span>=<span class="string">&quot;user&quot;</span>&gt;</span></span><br><span class="line">	select *</span><br><span class="line">    from tb_user</span><br><span class="line">    where </span><br><span class="line">    	username=#&#123;arg0&#125;</span><br><span class="line">    	and password=#&#123;param2&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
<li><p>运行程序则可以看到错误</p>
<p><img src="../images/assets/image-20210805231727206.png" alt="image-20210805231727206"></p>
</li>
</ul>
<p>==结论：以后接口参数是多个时，在每个参数上都使用 <code>@Param</code> 注解。这样代码的可读性更高。==</p>
<h4 id="1-10-2-单个参数"><a href="#1-10-2-单个参数" class="headerlink" title="1.10.2  单个参数"></a>1.10.2  单个参数</h4><ul>
<li><p>POJO 类型</p>
<p>直接使用。要求 <code>属性名</code> 和 <code>参数占位符名称</code> 一致</p>
</li>
<li><p>Map 集合类型</p>
<p>直接使用。要求 <code>map集合的键名</code> 和 <code>参数占位符名称</code> 一致</p>
</li>
<li><p>Collection 集合类型</p>
<p>Mybatis 会将集合封装到 map 集合中，如下：</p>
<blockquote>
<p>map.put(“arg0”，collection集合);</p>
<p>map.put(“collection”，collection集合;</p>
</blockquote>
<p>==可以使用 <code>@Param</code> 注解替换map集合中默认的 arg 键名。==</p>
</li>
<li><p>List 集合类型</p>
<p>Mybatis 会将集合封装到 map 集合中，如下：</p>
<blockquote>
<p>map.put(“arg0”，list集合);</p>
<p>map.put(“collection”，list集合);</p>
<p>map.put(“list”，list集合);</p>
</blockquote>
<p>==可以使用 <code>@Param</code> 注解替换map集合中默认的 arg 键名。==</p>
</li>
<li><p>Array 类型</p>
<p>Mybatis 会将集合封装到 map 集合中，如下：</p>
<blockquote>
<p>map.put(“arg0”，数组);</p>
<p>map.put(“array”，数组);</p>
</blockquote>
<p>==可以使用 <code>@Param</code> 注解替换map集合中默认的 arg 键名。==</p>
</li>
<li><p>其他类型</p>
<p>比如int类型，<code>参数占位符名称</code> 叫什么都可以。尽量做到见名知意</p>
</li>
</ul>
<h2 id="2，注解实现CRUD"><a href="#2，注解实现CRUD" class="headerlink" title="2，注解实现CRUD"></a>2，注解实现CRUD</h2><p>使用注解开发会比配置文件开发更加方便。如下就是使用注解进行开发</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Select(value = &quot;select * from tb_user where id = #&#123;id&#125;&quot;)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> User <span class="title">select</span><span class="params">(<span class="keyword">int</span> id)</span></span>;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>==注意：==</p>
<ul>
<li>注解是用来替换映射配置文件方式配置的，所以使用了注解，就不需要再映射配置文件中书写对应的 <code>statement</code></li>
</ul>
</blockquote>
<p>Mybatis 针对 CURD 操作都提供了对应的注解，已经做到见名知意。如下：</p>
<ul>
<li>查询 ：@Select</li>
<li>添加 ：@Insert</li>
<li>修改 ：@Update</li>
<li>删除 ：@Delete</li>
</ul>
<p>接下来我们做一个案例来使用 Mybatis 的注解开发</p>
<p><strong>代码实现：</strong></p>
<ul>
<li><p>将之前案例中 <code>UserMapper.xml</code> 中的 根据id查询数据 的 <code>statement</code> 注释掉</p>
<img src="../images/assets/image-20210805235229938.png" alt="image-20210805235229938" style="zoom:70%;"></li>
<li><p>在 <code>UserMapper</code> 接口的 <code>selectById</code> 方法上添加注解</p>
<img src="../images/assets/image-20210805235405070.png" alt="image-20210805235405070" style="zoom:70%;"></li>
<li><p>运行测试程序也能正常查询到数据</p>
</li>
</ul>
<p>我们课程上只演示这一个查询的注解开发，其他的同学们下来可以自己实现，都是比较简单。</p>
<p>==注意：==在官方文档中 <code>入门</code> 中有这样的一段话：</p>
<p><img src="../images/assets/image-20210805234302849.png" alt="image-20210805234302849"></p>
<p>所以，==注解完成简单功能，配置文件完成复杂功能。==</p>
<p>而我们之前写的动态 SQL 就是复杂的功能，如果用注解使用的话，就需要使用到 Mybatis 提供的SQL构建器来完成，而对应的代码如下：</p>
<img src="../images/assets/image-20210805234842497.png" alt="image-20210805234842497" style="zoom:70%;">

<p>上述代码将java代码和SQL语句融到了一块，使得代码的可读性大幅度降低。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://renshengdian.gitee.io/renshengdian/2021/11/17/Mybatis/" data-id="ckwp2cvnb00005cung02tgg0j" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/renshengdian/2021/12/02/%E4%B8%AD%E7%A7%91%E8%BE%BE/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          (no title)
        
      </div>
    </a>
  
  
    <a href="/renshengdian/2021/11/05/ide%E7%A4%BE%E5%8C%BA%E7%89%88%E9%80%82%E9%85%8D%E4%B8%8D%E4%BA%86tomcat/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">ide社区版适配不了tomcat</div>
    </a>
  
</nav>

  
</article>


</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/renshengdian/tags/ide/" rel="tag">ide</a></li><li class="tag-list-item"><a class="tag-list-link" href="/renshengdian/tags/jdk/" rel="tag">jdk</a></li><li class="tag-list-item"><a class="tag-list-link" href="/renshengdian/tags/mysql/" rel="tag">mysql</a></li><li class="tag-list-item"><a class="tag-list-link" href="/renshengdian/tags/tomcat/" rel="tag">tomcat</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/renshengdian/tags/ide/" style="font-size: 10px;">ide</a> <a href="/renshengdian/tags/jdk/" style="font-size: 20px;">jdk</a> <a href="/renshengdian/tags/mysql/" style="font-size: 10px;">mysql</a> <a href="/renshengdian/tags/tomcat/" style="font-size: 10px;">tomcat</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/renshengdian/archives/2021/12/">December 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/renshengdian/archives/2021/11/">November 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/renshengdian/archives/2021/10/">October 2021</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/renshengdian/2021/12/02/%E4%B8%AD%E7%A7%91%E8%BE%BE/">(no title)</a>
          </li>
        
          <li>
            <a href="/renshengdian/2021/11/17/Mybatis/">(no title)</a>
          </li>
        
          <li>
            <a href="/renshengdian/2021/11/05/ide%E7%A4%BE%E5%8C%BA%E7%89%88%E9%80%82%E9%85%8D%E4%B8%8D%E4%BA%86tomcat/">ide社区版适配不了tomcat</a>
          </li>
        
          <li>
            <a href="/renshengdian/2021/11/01/ide/">ide</a>
          </li>
        
          <li>
            <a href="/renshengdian/2021/11/01/jdk/">jdk</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2021 John Doe<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/renshengdian/" class="mobile-nav-link">Home</a>
  
    <a href="/renshengdian/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/renshengdian/js/jquery-3.4.1.min.js"></script>



  
<script src="/renshengdian/fancybox/jquery.fancybox.min.js"></script>




<script src="/renshengdian/js/script.js"></script>





  </div>
</body>
</html>